import { v4 as uuidv4 } from 'uuid';

/**
 * @description 字母转换(userName => user_name)
 * @param {string} key
 * @return {string} newKey
 */
export let humpToLine = (key) => {
    return key.replace(/([A-Z])/g, (a) => `_${a.toLocaleLowerCase()}`);
};

/**
 * @description 字母转换(user_name => userName)
 * @param {string} key
 * @return {string} newKey
 */
export let lineTohump = (key) => {
    return key.replace(/_(\w)/g, ([, $2]) => `${$2.toUpperCase()}`);
};

/**
 * @description path(/)替换为空
 * @param {string} path
 * @return {string} newpath
 */
export let slashTompty = (path) => path.replace(/\//g, '');

/**
 * @description path前缀加(/)
 * @param {string} path
 * @return {string} newpath
 */
export let slashprefix = (path) => (path.startsWith('/') ? path : `/${path}`);

/**
 * @description 路由转Map
 * @param {string} asyncRoutes 本地路由
 * @param {string} routesMap map
 * @param {string} basePath 路由url
 * @return {string} routesMap
 */
export let routesToMap = (asyncRoutes, routesMap = {}, basePath = '') => {
    asyncRoutes.forEach((item) => {
        // 去除path(/)方便map匹配
        item.path = slashTompty(item.path);
        let route = {...item };
        // 子菜单拼接sys/user
        route.paths = basePath ? `${basePath}/${route.path}` : `${route.path}`;
        if (item.children && item.children.length > 0) {
            delete route.children;
            routesMap[item.path.toUpperCase()] = route;
            routesToMap(item.children, routesMap, route.paths);
        } else {
            routesMap[item.path.toUpperCase()] = route;
        }
    });
    return routesMap;
};

/**
 * @description 生成菜单
 * @param {string} routesMap map
 * @param {string} routes 接口路由
 * @return {string} routes
 */
export let mappingRoutes = (routesMap, routes) => {
    routes.forEach((item) => {
        let route = routesMap[slashTompty(item.path).toUpperCase()];
        /**
         * 防止异常
         * 接口配置页面还未加路由的情况
         */
        if (route) {
            route.meta.title = item.name || route.meta.title;
            route.meta.icon = item.icon || route.meta.icon;
            item.meta = {...route.meta };
            item.redirect = item.redirect || route.redirect;
            item.hidden = item.hidden || route.hidden;
            item.component = route.component;
            // 拼接前缀(/)
            item.paths = slashprefix(route.paths);
            if (item.children && item.children.length > 0) {
                mappingRoutes(routesMap, item.children);
            }
        } else {
            item.hidden = true;
            item.meta = {};
        }
    });
    return routes;
};

/**
 *深拷贝 
 *deepCopy:防止指向同一个引用，即同一个对象 赋值2次。 防止引用冲突
 */
export let deepCopy = (value, map = new WeakMap()) => {
    if (value == null || typeof value !== 'object') return value;
    let deepData = new value.constructor();
    if (map.has(value)) return map.get(value);
    map.set(value, value);
    for (const key in value) {
        // eslint-disable-next-line no-prototype-builtins
        if (value.hasOwnProperty(key)) {
            deepData[key] = deepCopy(value[key], map);
        }
    }
    return deepData;
};

/**
 * @description 休眠
 * @param {Number} time 休眠时间毫秒
 * @returns
 */
export let sleep = (time) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve();
        }, time);
    });
};

/**
 *
 * 函数防抖
 * @param {*} callback 执行的函数
 * @param {*} delay 延迟的时间
 * @returns
 */
export function debounce(callback, delay) {
    let task;
    return function() {
        clearTimeout(task);
        task = setTimeout(() => {
            callback.apply(this, arguments);
        }, delay);
    };
}

/**
 * 列表转菜单
 * @param {*} list
 * @returns menu
 */
export let listToMenu = ({
    list = [],
    parentIdKey = 'parentId',
    idKey = ''
} = {}) => {
    let map = {};
    let menu = [];
    list.forEach((item) => {
        item.children = [];
        item.id = item[idKey];
        map[item[idKey]] = item;
        if (Number(item[parentIdKey]) === 0) {
            menu.push(item);
        } else {
            map[item[parentIdKey]] && map[item[parentIdKey]].children.push(item);
        }
    });
    return menu;
};

/**
 *
 * @param {*} list 元数据
 * @param {*} adaptiveMap 需要转换的key
 * @returns 新数据
 */
export let dataAdaptive = (list, adaptiveMap) => {
    list.forEach((item) => {
        Object.keys(item).forEach((key) => {
            // 需要转换的key
            if (adaptiveMap[key]) {
                item[adaptiveMap[key]] = item[key];
                delete item[key];
            }

            if (item.id) {
                let tempMap = deepCopy(item);
                if (tempMap.children) {
                    delete tempMap.children;
                } else if (Array.isArray(tempMap[key])) {
                    delete tempMap[key];
                }
            }

            // 默认children是子节点
            if (item.children && item.children.length > 0) {
                dataAdaptive(item.children, adaptiveMap);
            } else if (Array.isArray(item[key]) && item[key].length > 0) {
                dataAdaptive(item[key], adaptiveMap);
            }
        });
    });
    return list;
};

/**
 *  动态加载资源
 * @param {*} url 资源地址
 * @param {*} callback 加载完成后的回调函数
 * @param {*} type 资源类型
 */

export let loadScript = ({
    url,
    callback = () => {},
    type = 'script'
} = {}) => {
    var script = document.createElement(type);
    script.onload = () => callback();
    script.src = url;
    document.body.appendChild(script);
};

/**
 * uuid
 * @returns uuid
 */
export let uuid = () => {
    return uuidv4();
};

/**
 * 数组位置交换
 * @param {*} arr 需要交换的数组
 * @param {*} index1 // 位置1
 * @param {*} index2 // 位置2
 * @returns 交换后的数组
 */
export let swapArray = (arr, index1, index2) => {
    arr[index1] = arr.splice(index2, 1, arr[index1])[0];
    return arr;
};